<script setup lang="ts">
import Write from './page/Write.vue'
import { ContentDetailWrap } from '@/components/ContentDetailWrap'
import { PropType, h, ref, unref } from 'vue'
import { ElButton, ElInput, ElTag } from 'element-plus'
import { useI18n } from '@/hooks/web/useI18n'
import { useRoute, useRouter } from 'vue-router'
import { saveApi, getApi } from '@/api/lowcode'
import { useEmitt } from '@/hooks/event/useEmitt'
import { AllEvents, PageDataProperty } from '../../../types/Lowcode'

const props = defineProps({
  pageConfig: {
    type: Object as PropType<PageDataProperty>,
    required: true
  }
})

const { emitter } = useEmitt()

const { push, go } = useRouter()

const { params } = useRoute()

const { t } = useI18n()

const currentRow = ref<Nullable<any>>(null)

const getTableDet = async () => {
  const res = await getApi(props.pageConfig.detailApi, params.rid as string)
  if (res) {
    handleEvent('beforeLoad', res.data)
    currentRow.value = res.data
  }
}

const customFunction = (data: any, funcStr: string) => {
  const Fn = new Function('VUECustom', funcStr)
  let VUECustom = { h, ElTag, ElInput, data: data }
  return Fn(VUECustom)
}

const filterEventSchema = () => {
  let formSchemas = props.pageConfig.schemas
  let allEvents: AllEvents = { beforeLoadEvents: [], beforeSaveEvents: [], afterSaveEvents: [] }
  formSchemas.forEach((column) => {
    if (!column.form || !column.form.customEvents) {
      return
    }
    if (column.form.customEvents.beforeLoad) {
      allEvents.beforeLoadEvents.push(column)
    }
    if (column.form.customEvents.beforeSave) {
      allEvents.beforeSaveEvents.push(column)
    }
    if (column.form.customEvents.afterSave) {
      allEvents.afterSaveEvents.push(column)
    }
  })
  return allEvents
}

const allEvents = filterEventSchema()

const eventHaveReturnValue = ['beforeSaveEvents']

const handleEvent = (eventName: string, currentRow: any) => {
  if (!eventName) {
    console.log('parameter: event name is undefined.')
    return
  }
  let eventKey = eventName + 'Events'
  if (!allEvents[eventKey]) {
    // console.debug('parameter: event name ' + eventName + ' is empty.')
    return
  }
  // execute event
  let valid: boolean = true
  allEvents[eventKey].forEach((column) => {
    if (!column.form || !column.form.customEvents || !column.form.customEvents[eventName]) {
      return
    }
    let funcStr = column.form.customEvents[eventName]
    try {
      let result = customFunction(currentRow, funcStr)
      if (eventHaveReturnValue.indexOf(eventKey) > -1) {
        if (!result) {
          valid = false
        }
      }
    } catch (e: any) {
      console.error(e.message)
    }
  })
  return valid
}

getTableDet()

const writeRef = ref<ComponentRef<typeof Write>>()

const loading = ref(false)

const save = async () => {
  const write = unref(writeRef)
  const formData = await write?.submit()
  if (formData) {
    loading.value = true
    if (!handleEvent('beforeSave', formData)) {
      loading.value = false
      return
    }
    const res = await saveApi(props.pageConfig.editApi, formData)
      .catch(() => {})
      .finally(() => {
        loading.value = false
      })
    handleEvent('afterSave', res)
    if (res) {
      emitter.emit('getList', 'editor')
      push(`/lowcode/example-page/${props.pageConfig.id}`)
    }
  }
}
</script>

<template>
  <ContentDetailWrap :title="t('exampleDemo.edit')" @back="push('/example/example-page')">
    <Write ref="writeRef" :page-config="pageConfig" :current-row="currentRow" />

    <template #header>
      <ElButton @click="go(-1)">
        {{ t('common.back') }}
      </ElButton>
      <ElButton type="primary" :loading="loading" @click="save">
        {{ t('exampleDemo.save') }}
      </ElButton>
    </template>
  </ContentDetailWrap>
</template>
